#
#  Copyright (C) 2009 GSyC/LibreSoft
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
#    Author : Jose Antonio Santos Cadenas <jcaden __at__ gsyc __dot__ es>
#

# This file defines the api that must be used instead of accessing 
#  directly to the data models.
 
from django.contrib.gis.measure import D 
from django.contrib.contenttypes.models import ContentType

from search.utils import do_multi_search

from models import Person
from config import * 
import string

import privacy
import api_user as user
import api_group as group
import api_node as node
import api_note as note
import api_photo as photo
import api_sound as sound
import api_question as question

from utils import get_person
from social.privacy.exceptions import PermissionError

def get_version():
    return "0.3-dev" 
    
def tags(models, tag, viewer):
    """
    Returns a list
    """
    results={}
    try:
        v=get_person(viewer)
    except:
        return []
    for model in models:
        if model in ALLOWED_SEARCH:
            tagged=[]
            try:
                model_type = ContentType.objects.get(name=model, app_label="core").model_class() 
                for t in model_type.objects.filter(tags__tag=tag):
                    tagged+=[t.get_dictionary(v)]
            except:
                pass
            results[model]=tagged
    return results

def search(user, models, terms, dist=-1):
    """
    Uses the search application and returns the results
    
    @param user: The user that makes the request
    @param models_fields: A list with the models
    @param terms: the search terms
    @param dist: the maximum distance to the requester, if negative 
                 all matching nodes will be returned.  
    """
    
    try:
        v=get_person(user)
    except:
        return []
    m_f=[]
    
    for model in models:
        if model in ALLOWED_SEARCH:
            try:
                model_type = ContentType.objects.get(name=model, app_label="core").model_class()
                m_f += [{"type": model_type, "fields": model_type.get_search_fields}]
            except:
                pass
    
    results= do_multi_search(m_f, terms, v)
    if results == False:
        return False
    #Now filter by distance if requested
    if dist >= 0:
        p = Person.objects.get(pk=user)
        for model in models:
            results[model]=results[model].distance(p.position).order_by("distance"
                     ).filter(position__distance_lte=(p.position, D(km=float(dist))))
    elif []==string.split(terms):
        #This case is when there are no restrictions, in this case nothing is returned
        #TODO: review if this is a good policy
        for model in models:
            model_type = ContentType.objects.get(name=model, app_label="core").model_class()
            results[model]=model_type.objects.none()
    for model in models:
        res= []
        for i in results[model]:
            try:
                res += [i.get_node().get_dictionary(v)]
            except PermissionError:
                pass
        results[model]=res    
    return results
